﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;
using umbraco;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.media;
using uREST.CMS.Extensions;

namespace uREST.CMS.MediaFactories
{
    public abstract class UmbracoMediaFactory : IMediaFactoryCreator, IMediaFactoryUpdater
    {
        public const string MEDIA_DIR = "/media";

        public UmbracoMediaFactory(string mediaTypeAlias)
        {
            MediaTypeAlias = mediaTypeAlias;
        }

        public string MediaTypeAlias { get; protected set; }

        public abstract List<string> Extensions { get; }
        public virtual int Priority { get { return 1000; } }

        public virtual bool CanCreateMedia(int parentNodeId, UploadedFile uploadedFile, User user)
        {
            try
            {
                var parentNode = new Media(parentNodeId);

                return parentNodeId > -1 ?
                    user.CanAccess(parentNode) && parentNode.ContentType.AllowedChildContentTypeIDs.Contains(MediaType.GetByAlias(MediaTypeAlias).Id) : 
                    true;
            }
            catch
            {
                return false;
            }
        }

        public virtual bool CanUpdateMedia(int id, UploadedFile uploadedFile, User user)
        {
            try
            {
                var node = new Media(id);

                return user.CanAccess(node) && node.ContentType.Alias == MediaTypeAlias;
            }
            catch 
            {
                return false;
            }
        }

        public Media CreateMedia(int parentNodeId, UploadedFile uploadedFile, User user)
        {
            var media = Media.MakeNew(uploadedFile.FileName,
                MediaType.GetByAlias(MediaTypeAlias),
                user,
                parentNodeId);

            if (uploadedFile.ContentLength > 0)
                HandleMedia(media, uploadedFile, user);

            // Genereate xml cache
            media.XmlGenerate(new XmlDocument());

            return media;
        }

        public Media UpdateMedia(int id, UploadedFile uploadedFile, User user)
        {
            var media = new Media(id);

            if (uploadedFile.ContentLength > 0)
                HandleMedia(media, uploadedFile, user);

            // Genereate xml cache
            media.XmlGenerate(new XmlDocument());

            return media;
        }

        public abstract void HandleMedia(Media media, UploadedFile uploadedFile, User user);

        #region Helper Methods

        public string ConstructDestPath(int propertyId)
        {
            if (UmbracoSettings.UploadAllowDirectories)
            {
                var path = VirtualPathUtility.Combine(VirtualPathUtility.AppendTrailingSlash(MEDIA_DIR), propertyId.ToString());

                return VirtualPathUtility.ToAbsolute(VirtualPathUtility.AppendTrailingSlash(path));
            }

            return VirtualPathUtility.ToAbsolute(VirtualPathUtility.AppendTrailingSlash(MEDIA_DIR));
        }

        public string ConstructDestFileName(int propertyId, string filename)
        {
            if (UmbracoSettings.UploadAllowDirectories)
                return filename;

            return propertyId + "-" + filename;
        }

        #endregion
    }
}
